var chill_bookmarklet = (function() {

    // Add ECMA262-5 Array methods if not supported natively
    //
    if (!('indexOf' in Array.prototype)) {
        Array.prototype.indexOf= function(find, i /*opt*/) {
            if (i===undefined) i= 0;
            if (i<0) i+= this.length;
            if (i<0) i= 0;
            for (var n= this.length; i<n; i++)
                if (i in this && this[i]===find)
                    return i;
            return -1;
        };
    }

    var YOUTUBE_IFRAME_REGEX = /^http:\/\/www.youtube.com\/embed\/([-\w]+)/
    var VIMEO_IFRAME_REGEX = /^http:\/\/player.vimeo.com\/video\/(\d+)/

    // some things we need in here
    var host = 'http://chill.com',
    iframe_url = host + '/bookmarklet/loading',
    bVer = 'xxx', //bookmarklet version
    lVer = '1.0.1',  //loader version
    doc = document,
    head = doc.getElementsByTagName('head')[0],
    body = doc.getElementsByTagName('body')[0],
    messageListeners = [],
    _bookmarklet;
 
    // general utils
    var Utils = {

        getWindowBox: function(){
            // summary:
            //		Returns the dimensions and scroll position of the viewable area of a browser window

            var scrollRoot = (dojo.doc.compatMode == 'BackCompat') ? dojo.body() : dojo.doc.documentElement;

            // get scroll position
            var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
            return {
                w: scrollRoot.clientWidth,
                h: scrollRoot.clientHeight,
                l: scroll.x,
                t: scroll.y
            };
        },

        // load a javascript file
        loadJs: function(src) {
            var js = doc.createElement('script');
            js.type = 'text/javascript';
            js.src = src;
            js.async = true;
            head.appendChild(js);
        },

        addMessageListener: function(message, callback) {
            messageListeners[message] = callback;
        },

        //borrow from dojo.regex
        regexpEscapeString: function(/*String*/str, /*String?*/except){
            //	summary:
            //		Adds escape sequences for special characters in regular expressions
            // except:
            //		a String with special characters to be left unescaped

            return str.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(ch){
                if(except && except.indexOf(ch) != -1){
                    return ch;
                }
                return "\\" + ch;
            }); // String
        },

        //borrowed from dojo.cookie
        cookie: function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/props){
            //	summary:
            //		Get or set a cookie.
            //	description:
            // 		If one argument is passed, returns the value of the cookie
            // 		For two or more arguments, acts as a setter.
            //	name:
            //		Name of the cookie
            //	value:
            //		Value for the cookie
            //	props:
            //		Properties for the cookie
            //	example:
            //		set a cookie with the JSON-serialized contents of an object which
            //		will expire 5 days from now:
            //	|	dojo.cookie("configObj", dojo.toJson(config), { expires: 5 });
            //
            //	example:
            //		de-serialize a cookie back into a JavaScript object:
            //	|	var config = dojo.fromJson(dojo.cookie("configObj"));
            //
            //	example:
            //		delete a cookie:
            //	|	dojo.cookie("configObj", null, {expires: -1});
            var c = document.cookie;
            if(arguments.length == 1){
                var matches = c.match(new RegExp("(?:^|; )" + dojo.regexp.escapeString(name) + "=([^;]*)"));
                return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined
            }else{
                props = props || {};
                // FIXME: expires=0 seems to disappear right away, not on close? (FF3)  Change docs?
                var exp = props.expires;
                if(typeof exp == "number"){
                    var d = new Date();
                    d.setTime(d.getTime() + exp*24*60*60*1000);
                    exp = props.expires = d;
                }
                if(exp && exp.toUTCString){
                    props.expires = exp.toUTCString();
                }

                value = encodeURIComponent(value);
                var updatedCookie = name + "=" + value, propName;
                for(propName in props){
                    updatedCookie += "; " + propName;
                    var propValue = props[propName];
                    if(propValue !== true){ 
                        updatedCookie += "=" + propValue;
                    }
                }
                document.cookie = updatedCookie;
            }
        }
    }

    var postMessageCallback = function(e) {
        var message = JSON.parse(e.data);

        // check if the window is trying to execute
        // some arbitrary custom event
        if(message.event===undefined && message.name in messageListeners) {
            messageListeners[message.name](message.args);
        }
    }

    if (window.addEventListener){
        window.addEventListener('message', postMessageCallback, false);
    } else {
        //IE8 uses attachEvent not addEventListener
        window.attachEvent("onmessage", postMessageCallback)
        window.attachEvent("message", postMessageCallback)
    }

    // listen for calls from iframe
    Utils.addMessageListener('unload-bookmarklet', function() {
        _bookmarklet.hide();
    });

    Utils.addMessageListener('resize-iframe', function(dimensions) {
        _bookmarklet.resize(dimensions);
    });

    // creates a way to proxy
    // POST methods to the website directly
    var Bookmarklet = function(path){
        var _b = {
            constructor: function(path) {
                this.postProcessPage()
                this.destroyWrapper(this.wrapperNodes)
                this.destroyIframe(this.iframe)

                var d = document.getElementById('chill-loading-message')
                if (d){
                    d.parentNode.removeChild(d)
                }

                body.style.overflow = 'hidden'
                this.preProcessPage()
                this.wrapperNodes = this.createWrapper()
                this.iframe = this.createIframe(path);

                var c = this,
                cw = this.iframe.contentWindow;

                // provide a way for bookmarklet
                // to trigger custom events in iframe
                this.trigger = function(event, args) {
                    cw.postMessage({
                        event: event,
                        args: args
                    }, '*');

                }
                
                return this;
            },

            preProcessPage: function(){
                //Any actions necessary to sanitize page
                var iftags = document.getElementsByTagName('iframe')
                for(i=0; i<iftags.length; i++) {
                    var _if = iftags[i]
                    _if.style.visibility = 'hidden'
                    this._processedIframes.push(_if)
                }
            },

            postProcessPage: function(){
                //Revert actions in postProcess
                if (this._processedIframes){
                    for(i=0; i<this._processedIframes.length; i++) {
                        var _if = this._processedIframes[i]
                        _if.style.visibility = ''
                    }
                }
                this._processedIframes = []
            },

            // generate the iframe to proxy
            createIframe: function(url) {
                var di = document.getElementById('chill_inner_wrapper')

                var i = document.createElement('iframe');
                i.src = url
                i.name = 'chill_post_iframe'
                i.style.width='100%'
                i.style.height='120px'
                i.frameborder = '0'
                i.id = 'chill-bookmarklet-iframe'

                i.style.background = "url('http://d3ar1agdggt2nn.cloudfront.net/static-versioned/1c5f81204ef4a115a3cf0ecd1d04c67a.png') repeat";
                i.style.border = '0'

                di.appendChild(i);

                return i;
            },

            destroyIframe: function(_if){
                _if = _if || document.getElementById('chill-bookmarklet-iframe')
                if (_if){
                    if (this.iframe==_if){
                        this.iframe = null;
                    }
                    _if.parentNode.removeChild(_if);
                }
            },

            // generate the wrapper for the page to place the iframe in
            createWrapper: function() {
                var ul = document.createElement('div')
                ul.id = "chill_underlay"
                ul.style.position = 'fixed'
                ul.style.top = '0px'
                ul.style.bottom = '0px'
                ul.style.left = '0px'
                ul.style.right = '0px'
                ul.style.background = 'white'
                ul.style.zIndex=1999999999

                //TODO: IE handles opacity differently
                ul.style.opacity = 0.95
            
                var dw = document.createElement('div')
                dw.id = "chill_outer_wrapper"
                dw.style.position = 'fixed'
                dw.style.top = '0'
                dw.style.left = '0'
                dw.style.width = '100%'
                dw.style.zIndex = 2000000000

                var di = document.createElement('div')
                di.id = "chill_inner_wrapper"
                dw.appendChild(di);

                document.body.appendChild(ul);
                document.body.appendChild(dw);

                return [ul, dw, di]
            },

            destroyWrapper: function(wrapperNodes){
                if (wrapperNodes && wrapperNodes.length>0){
                    for(i=0; i<wrapperNodes.length; i++) {
                        document.body.removeChild(wrapperNodes[i]);
                    }
                } else if (wrapperNodes && wrapperNodes.length>0) {
                    for(i=0; i<this.wrapperNodes.length; i++) {
                        document.body.removeChild(this.wrapperNodes[i]);
                    }
                    this.wrapperNodes = []
                } else {
                    var di = document.getElementById('chill_inner_wrapper')
                    if (di && di.parentNode){
                        di.parentNode.removeChild(di);
                    }

                    var dw = document.getElementById('chill_outer_wrapper')
                    if (dw && dw.parentNode){
                        dw.parentNode.removeChild(dw);
                    }

                    var ul = document.getElementById('chill_underlay')
                    if (ul && ul.parentNode){
                        ul.parentNode.removeChild(ul);
                    }
                }
            },

            hide: function() {
                this.destroyIframe()
                this.destroyWrapper()
                this.postProcessPage()
                body.style.overflow = ''
            },

            resize: function(dimensions) {
                var height = dimensions.h || dimensions.height
                var winHeight = window.innerHeight
                if (winHeight<height){
                    this.iframe.style.height=winHeight+'px'
                } else {
                    this.iframe.style.height=height+'px'
                }
            }

        };

        return _b.constructor(path)
    };

    function addVideoEmbed(embeds, url) {
        //Not the most efficent, but simple de-dup
        if(embeds.indexOf(url)==-1) {
            embeds.push(url)
        }
    };

    function addVideoItem(items, url) {
        //Not the most efficent, but simple de-dup
        if(items.indexOf(url)==-1) {
            items.push(url)
        }
    };

    function getVideoEmbeds() {
        var embeds = [];
        var items = [];
        var src = null;

        var iftags = document.getElementsByTagName('iframe')
        for(i=0; i<iftags.length; i++) {
            var _if = iftags[i]
            src = _if.getAttribute('src')
            if(src) {
                var youtubeMediaId = YOUTUBE_IFRAME_REGEX.exec(src)
                var vimeoMediaId = VIMEO_IFRAME_REGEX.exec(src)
                if (youtubeMediaId){
                    addVideoItem(items, ['youtube', youtubeMediaId[1]])
                } else if (vimeoMediaId){
                    addVideoItem(items, ['vimeo', vimeoMediaId[1]])
                }
            }
        }
        
        var objtags = document.getElementsByTagName('object')
        for(i=0; i<objtags.length; i++) {
            var ot = objtags[i]
            var paramtags = ot.getElementsByTagName('param')
            for(j=0;j<paramtags.length; j++) {
                var pt = paramtags[j];
                var attrname = pt.getAttribute('name');
                if(attrname && attrname.toLowerCase()=='src') {
                    src = pt.getAttribute('value');
                    if(src) {
                        addVideoEmbed(embeds, src);
                    }
                }
            }
        }

        var embtags = document.getElementsByTagName('embed')
        for(i=0; i<embtags.length; i++) {
            var et = embtags[i]
            src = et.getAttribute('src')
            if(src) {
                addVideoEmbed(embeds, src)
            }
        }

        return [embeds, items]
    };

    function buildUrlString(embedData) {
        var query_string = '?bver='+bVer+'&lver='+lVer;
        query_string += '&loc=' + encodeURIComponent(window.location)
        var embeds = embedData[0]
        var items = embedData[1]
        var i, item, emb, itemData;

        if (items.length>0){
            for(i=0; i<items.length; i++) {
                item = items[i]
                if(item.length>1) {
                    itemData = item[0]+'::'+item[1]
                    query_string += '&items=' + encodeURIComponent(itemData)
                }
            }
        }

        if(embeds.length>0) {
            for(i=0; i<embeds.length; i++) {
                emb = embeds[i]
                if(emb.length>1) {
                    if(i==0) {
                        query_string += '&' // for now, there's something before it
                    }
                    else {
                        query_string += '&'
                    }
                    query_string += 'emb=' + encodeURIComponent(emb)
                }
            }
        }
        return iframe_url + query_string
    };
    
    function init() {
        var embedData = getVideoEmbeds();
        //var embeds = embedData[0]
        //var items = embedData[1];
        //alert(embeds);
       // alert(items)
        iframe_url = buildUrlString(embedData)
        alert(iframe_url);
        // create bookmarklet channel
        return new Bookmarklet(iframe_url);
    };
    
    _bookmarklet = init();

    return _bookmarklet;

})();